/**
 * Copyright (c) aunigold, Inc All Rights Reserved.
 */

package com.longau.guinea;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.longau.guinea.bo.Price;
import com.longau.guinea.bo.SortPrice;
import com.longau.guinea.bo.Stock;
import com.longau.guinea.bo.Udp;
import com.longau.guinea.core.WsGetwsz;
import com.longau.guinea.util.ConfigurationUtil;
import com.longau.guinea.util.JsonBinder;

/**
 * Server
 * 
 * @author gaokun
 * @version 1.0, Created on 2017年9月20日
 */
public class Server {
	private static Logger logger = LoggerFactory.getLogger(Server.class);
	private DatagramPacket sendPacket = null;
	private DatagramSocket sendSocket = null;
	private Map<String, String> map = new ConcurrentHashMap<String, String>();
	private Map<String, String[]> marketMap = new ConcurrentHashMap<String, String[]>();
	private Map<String, Udp> udpMap = new ConcurrentHashMap<String, Udp>();
	private Random random = new Random(System.currentTimeMillis());
	private InetAddress address = null;

	public Server() {
		try {
			sendSocket = new DatagramSocket();
		} catch (SocketException e) {
			logger.error(e.getMessage());
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new Server().send();
	}

	private void send() {
		String tURL = ConfigurationUtil.getProperty("wstock.url"); // 微盛推送式HTTP
//		String[] udpips = ConfigurationUtil.getStringArray("UDP_IP");
//		String[] udpports = ConfigurationUtil.getStringArray("UDP_PORT");
//
//		String[] hudpips = ConfigurationUtil.getStringArray("H_UDP_IP");
//		String[] hudpports = ConfigurationUtil.getStringArray("H_UDP_PORT");

		String market_quotation = ConfigurationUtil.getProperty("MARKET_QUOTATION");
		String custom_udp = ConfigurationUtil.getProperty("CUSTOM_UDP");

		String encoding = "a"; // utf-8
		String filename = "";

		installMap(market_quotation, custom_udp);
		while (true) {
			try {
				Thread.sleep(800); // 300毫秒请求一次
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			// String str = HttpUtil.httpClientPost(tURL);// WsGetwsz.wsDownload(tURL,
			// encoding, filename); // 获取微盛推送式实时行情
			String str = WsGetwsz.wsDownload(tURL, encoding, filename); // 获取微盛推送式实时行情
			/*
			 * try { str = HttpClientUtil.httpGet(tURL); } catch (IOException e1) { // TODO
			 * Auto-generated catch block logger.error("请求错误!"); } //
			 */
			/*
			 * if (str != null && str.endsWith("]")) { List<Stock> beanList = null; try {
			 * beanList = JsonBinder.buildNormalBinder().getMapper().readValue(str, new
			 * TypeReference<List<Stock>>() { }); } catch (IOException e1) {
			 * logger.error("得到错误数据"); } for (Stock s : beanList) { if
			 * (map.get(s.getSymbol()) == null ||
			 * (!map.get(s.getSymbol()).equals(s.getClose()))) { map.put(s.getSymbol(),
			 * s.getClose()); if (s.getSymbol().equals("BTC")) { s.setSymbol("BTCUSD");
			 * String bean = transform(s); for (int i = 0; i < udpips.length; i++) {
			 * logger.info("发送开始:" + udpips[i] + ":" + udpports[i] + bean); try { sendPacket
			 * = new DatagramPacket(bean.getBytes(), bean.getBytes().length,
			 * InetAddress.getByName(udpips[i]), Integer.parseInt(udpports[i]));
			 * sendSocket.send(sendPacket); } catch (IOException e) {
			 * logger.error(e.getMessage()); } } } } } }
			 */
			/*
			 * 苹果 if (str != null&&str.endsWith("]")) { List<Stock> beanList = null; try {
			 * beanList = JsonBinder.buildNormalBinder().getMapper().readValue(str, new
			 * TypeReference<List<Stock>>() { }); } catch (IOException e1) {
			 * logger.error("得到错误数据"); } for (Stock s : beanList) { if
			 * (map.get(s.getSymbol()) == null ||
			 * (!map.get(s.getSymbol()).equals(s.getClose()))) { map.put(s.getSymbol(),
			 * s.getClose()); if (s.getSymbol().equals("AAPL")) { String bean =
			 * transform(s); sendPacket = new DatagramPacket(bean.getBytes(),
			 * bean.getBytes().length, address,
			 * ConfigurationUtil.getPropertyForInt("UDP_PORT")); try {
			 * sendSocket.send(sendPacket); } catch (IOException e) {
			 * logger.error(e.getMessage()); } logger.info(bean); } } } }
			 */
			// BT币 国外交易所
			/*
			 * if (str != null && str.endsWith("]") && (str.indexOf("error") == -1)) {
			 * String sortStr = str.substring(1, str.length() - 1); 伪造 if (map.get("BTCUSD")
			 * != null && map.get("BTCUSD").equals(sortStr)) { int flag = (int) (1 +
			 * Math.random() * 10); if (flag > 3) { logger.info("假"); send(sortStr, udpips,
			 * udpports, random(random)); } } if (map.get("BTCUSD") == null ||
			 * (!map.get("BTCUSD").equals(sortStr))) { send(sortStr, udpips, udpports,
			 * null); // logger.info(bean); } }
			 */
			// 威盛

			String[] split = str.split("\r\n");
			if (!ArrayUtils.isEmpty(split)) {
				for (String s : split) {
					// logger.info("數據源====》"+s);
					String bean = "";
					String[] innerSplit = s.split(",");
					/*
					 * if (innerSplit.length > 2 && (innerSplit[1].equalsIgnoreCase("FXEURUSD") ||
					 * innerSplit[1].equalsIgnoreCase("IPBRNA0") ||
					 * innerSplit[1].equalsIgnoreCase("CMHGI0") ||
					 * innerSplit[1].equalsIgnoreCase("CMSII0"))) { if (innerSplit.length == 8) {
					 * bean = installSortBean(innerSplit); } else if (innerSplit.length == 34) {
					 * bean = installBean(innerSplit); } }
					 */

					for (Entry<String, String[]> mEntry : marketMap.entrySet()) {
						if (innerSplit.length > 2 && (ArrayUtils.contains(mEntry.getValue(), innerSplit[1]))) {
							if (innerSplit.length == 8) {
								bean = installSortBean(innerSplit);
							} else if (innerSplit.length == 34) {
								bean = installBean(innerSplit);
							}
						}
						if (StringUtils.isNotBlank(bean)) {
							Udp udp = udpMap.get(mEntry.getKey());
							logger.info("发送开始:" + udp.getIp() + ":" + udp.getPort() + bean);
							try {
								sendPacket = new DatagramPacket(bean.getBytes(), bean.getBytes().length,
										InetAddress.getByName(udp.getIp()), udp.getPort());
								sendSocket.send(sendPacket);
							} catch (IOException e) {
								logger.error(e.getMessage());
							}
						}
						bean = "";
					}
					// installBean(s);
					/*
					 * sendPacket = new DatagramPacket(bean.getBytes(), bean.getBytes().length,
					 * address, ConfigurationUtil.getPropertyForInt("UDP_PORT")); try {
					 * sendSocket.send(sendPacket); } catch (IOException e) {
					 * logger.error(e.getMessage()); }
					 */
					/*
					 * if (StringUtils.isNotBlank(bean)) { for (int i = 0; i < udpips.length; i++) {
					 * logger.info("发送开始:" + udpips[i] + ":" + udpports[i] + bean); try { sendPacket
					 * = new DatagramPacket(bean.getBytes(), bean.getBytes().length,
					 * InetAddress.getByName(udpips[i]), Integer.parseInt(udpports[i]));
					 * sendSocket.send(sendPacket); } catch (IOException e) {
					 * logger.error(e.getMessage()); } } // logger.info(bean); }
					 * 
					 * 黄总 String hbean = ""; if (innerSplit.length > 2 &&
					 * (innerSplit[1].equalsIgnoreCase("FXEURUSD") ||
					 * innerSplit[1].equalsIgnoreCase("NECLA0") ||
					 * innerSplit[1].equalsIgnoreCase("LECAD3M") ||
					 * innerSplit[1].equalsIgnoreCase("FXXAGUSD"))) { if (innerSplit.length == 8) {
					 * hbean = installSortBean(innerSplit); } else if (innerSplit.length == 34) {
					 * hbean = installBean(innerSplit); } } if (StringUtils.isNotBlank(hbean)) { for
					 * (int i = 0; i < hudpips.length; i++) { logger.info("发送开始:" + hudpips[i] + ":"
					 * + hudpports[i] + hbean); try { sendPacket = new
					 * DatagramPacket(hbean.getBytes(), hbean.getBytes().length,
					 * InetAddress.getByName(hudpips[i]), Integer.parseInt(hudpports[i]));
					 * sendSocket.send(sendPacket); } catch (IOException e) {
					 * logger.error(e.getMessage()); } } // logger.info(bean); }
					 * 
					 * 龙讯 if (innerSplit.length > 2 && (innerSplit[1].startsWith("FX"))) { try {
					 * byte[] bytes = installSortBean(innerSplit).getBytes(); new
					 * DatagramSocket().send(new DatagramPacket(bytes, bytes.length,
					 * InetAddress.getByName("59.110.159.148"), 1012)); //
					 * logger.info("发送开始:59.110.159.148:1012"+new String(bytes)); } catch
					 * (IOException e) { logger.error(e.getMessage()); } }
					 */
				}
			}

		}
	}

	private void send(String sortStr, String[] udpips, String[] udpports, Double mockPrice) {
		map.put("BTCUSD", sortStr);
		// String bean = installSortBean(sortStr, mockPrice);
		String bean = "";// installSortBean(sortStr);
		for (int i = 0; i < udpips.length; i++) {
			logger.info("发送开始:" + udpips[i] + ":" + udpports[i] + bean);
			try {
				sendPacket = new DatagramPacket(bean.getBytes(), bean.getBytes().length,
						InetAddress.getByName(udpips[i]), Integer.parseInt(udpports[i]));
				sendSocket.send(sendPacket);
			} catch (IOException e) {
				logger.error(e.getMessage());
			}
		}
	}

	private String installBean(String[] split) {
		Price json = new Price();
		if (!ArrayUtils.isEmpty(split)) {
			for (int i = 0; i < split.length; i++) {
				if (i == 0) {
					json.setQuoteTime(split[i]);
				} else if (i == 1) {
					json.setCode(split[i]);
				} else if (i == 2) {
					json.setName(split[i]);
				} else if (i == 3) {
					json.setPrice(split[i]);
				} else if (i == 4) {
					json.setVol(split[i]);
				} else if (i == 5) {
					// 持仓或保留
				} else if (i == 6) {
					// 结算价或保留
				} else if (i == 7) {
					json.setLastClose(split[i]);
				} else if (i == 8) {
					json.setOpen(split[i]);
				} else if (i == 9) {
					json.setHigh(split[i]);
				} else if (i == 10) {
					json.setLow(split[i]);
				} else if (i == 11) {
					json.setLast(split[i]);
				} else if (i == 12) {
					json.setVolume(split[i]);
				} else if (i == 13) {
					json.setTotal(split[i]);
				} else if (i == 14) {
					json.setBid1(split[i]);
				} else if (i == 15) {
					json.setBid2(split[i]);
				} else if (i == 16) {
					json.setBid3(split[i]);
				} else if (i == 17) {
					json.setBid4(split[i]);
				} else if (i == 18) {
					json.setBid5(split[i]);
				} else if (i == 19) {
					json.setBidlot1(split[i]);
				} else if (i == 20) {
					json.setBidlot2(split[i]);
				} else if (i == 21) {
					json.setBidlot3(split[i]);
				} else if (i == 22) {
					json.setBidlot4(split[i]);
				} else if (i == 23) {
					json.setBidlot5(split[i]);
				} else if (i == 24) {
					json.setAsk1(split[i]);
				} else if (i == 25) {
					json.setAsk2(split[i]);
				} else if (i == 26) {
					json.setAsk3(split[i]);
				} else if (i == 27) {
					json.setAsk4(split[i]);
				} else if (i == 28) {
					json.setAsk5(split[i]);
				} else if (i == 29) {
					json.setAsklot1(split[i]);
				} else if (i == 30) {
					json.setAsklot2(split[i]);
				} else if (i == 31) {
					json.setAsklot3(split[i]);
				} else if (i == 32) {
					json.setAsklot4(split[i]);
				} else if (i == 33) {
					json.setAsklot5(split[i]);
				}
			}
		}
		return JsonBinder.buildNormalBinder().toJson(json);
	}

	private String installSortBean(String str, Double mockPrice) {
		SortPrice json = new SortPrice();
		String[] split = str.split(",");
		if (!ArrayUtils.isEmpty(split)) {
			json.setCode("BTCUSD");
			// json.setQuoteTime(new Date());
			for (int i = 0; i < split.length; i++) {
				if (i == 0) {
					String buy = mockPrice == null ? split[i]
							: String.format("%.1f", Double.valueOf(split[i]) + 1 + mockPrice);
					json.setBuy(buy);
				} else if (i == 2) {
					String sell = mockPrice == null ? split[i]
							: String.format("%.1f", Double.valueOf(split[i]) + 1 + mockPrice);
					json.setSell(sell);
				} else if (i == 8) {
					String high = map.get("HIGH") != null ? map.get("HIGH") : split[i];// 如果第一次没有最高,则取真值,否则取假值
					if (mockPrice != null) {
						Double last = Double.valueOf(split[6]) + 1 + mockPrice;
						if (last > Double.valueOf(high)) {
							high = String.format("%.1f", last);
						}
					}
					json.setHigh(high);
					map.put("HIGH", high);
				} else if (i == 9) {
					String low = map.get("LOW") != null ? map.get("LOW") : split[i];// 如果第一次没有最低,则取真值,否则取假值
					if (mockPrice != null) {
						Double last = Double.valueOf(split[6]) + 1 + mockPrice;
						if (last < Double.valueOf(low)) {
							low = String.format("%.1f", last);
						}
					}
					map.put("LOW", low);
					json.setLow(low);
				} else if (i == 6) {
					String last = mockPrice == null ? split[i]
							: String.format("%.1f", Double.valueOf(split[i]) + 1 + mockPrice);
					json.setLast(last);
				}
			}
		}
		return JsonBinder.buildNormalBinder().toJson(json);
	}

	private String transform(Stock stock) {
		SortPrice json = new SortPrice();
		// json.setBuy(stock.get);
		json.setCode(stock.getSymbol());
		json.setHigh(stock.getHigh());
		json.setLast(stock.getClose());
		json.setLastClose(stock.getPclose());
		json.setLow(stock.getLow());
		json.setOpen(stock.getOpen());
		// try {
		// // json.setQuoteTime(new SimpleDateFormat("yyyy-MM-dd
		// hh:mm:ss").parse(stock.getDateTime()));
		// } catch (ParseException e) {
		// e.printStackTrace();
		// }
		// json.setSell(sell);
		return JsonBinder.buildNormalBinder().toJson(json);
	}

	private static Double random(Random random) {
		int max = 20;
		int min = -6;
		int s = random.nextInt(max) % (max - min + 1) + min;
		return Double.valueOf(String.valueOf(s));
	}

	private String installSortBean(String[] split) {
		SortPrice json = new SortPrice();
		if (!ArrayUtils.isEmpty(split)) {
			for (int i = 0; i < split.length; i++) {
				if (i == 0) {
					json.setQuoteTime(split[i]);
				} else if (i == 1) {
					json.setCode(split[i]);
				} else if (i == 3) {
					json.setOpen(split[i]);
				} else if (i == 4) {
					json.setHigh(split[i]);
				} else if (i == 12) {
					// json.setLastClose(split[i]);
				} else if (i == 5) {
					json.setLow(split[i]);
				} else if (i == 12) {
					// json.setLast(split[i]);
				} else if (i == 6) {
					json.setBuy(split[i]);
				} else if (i == 7) {
					json.setSell(split[i]);

				}
			}
		}
		return JsonBinder.buildNormalBinder().toJson(json);
	}

	private void installMap(String market_quotation, String custom_udp) {
		String[] market = market_quotation.split("-");

		for (String m : market) {
			String[] childMarket = m.split("\\|");
			marketMap.put(childMarket[0], childMarket[1].split("\\,"));
		}

		String[] custom = custom_udp.split("-");
		for (String c : custom) {
			String[] childCustom = c.split("\\|");
			String[] udp = childCustom[1].split(":");
			udpMap.put(childCustom[0], new Udp(udp[0], Integer.parseInt(udp[1])));
		}
	}
}
